/**
 * Created by Administrator on 2016/9/9.
 */

// 自定义 jq插件

// 使用：每条数据一定要有“id”字段。colModal数组的 index 与对应的字段名要相同，id的字段名叫“id”
// 数据格式 ：data.json

// 要修改 reloadData（）方法

;(function($){

    /***************** jqGrid 类 **********************/
    var jqGrid = function( handle, url, data, colName, colModal, height, isSelectAll, isTrash, editUrl ) { // 构造函数 （handle 是承载表格 的容器）

        // 必填 （重新加载数据时要用到）
        this.handle = handle;
        this.url = url;
        this.colName = colName;
        this.colModal = colModal;
        this.editUrl = editUrl;

        // 选填
        var _height = ( $(window).height() - handle.offset().top ) * 0.85 - 70 - 60;// 默认高度（减去thead、tfoot）
        this.height = ( height == undefined ? _height + 'px' : height );
        this.isSelectAll = ( isSelectAll == undefined ? false : isSelectAll ); // 全选按钮
        this.isTrash = ( ( isTrash == undefined  ||  !this.isSelectAll ) ? false : isTrash );// 没有全选按钮，则不显示删除按钮

        // 存放表格 jq对象
        this.$table = $( '<div id="' + this.handle.attr('id') + '_jqGrid" class="' + this.handle.attr('class') + '">'
            + '<div class="jqGrid-head"><table><thead></thead></table></div>'
            + '<div class="jqGrid-body" style="height: ' + this.height +'"><table><tbody></tbody></table></div></div>' );

        // 存放翻页按钮 jq对象
        this.$page = $('<div class="jqGrid-page"><div class="opBtnBox"><i class="fa fa-refresh"></i></div>'
                    + '<ul class="pageBox" id="' + this.handle.attr('id') + '_jqGrid-page"></ul><div class="tipBox"></div></div>');

        this.addRefreshEvent(); // 给 刷新按钮 添加点击事件
        this.addPageEvent(); // 给 翻页按钮 添加点击事件
        if( this.isTrash ){ // 有 删除按钮
            this.$page.find('.opBtnBox').prepend( $('<i class="fa fa-trash"></i>') );
            this.addTrashEvent(); // 给 删除按钮 添加点击事件
        }

        // 表格、翻页 插入到页面
        this.handle.empty().append( this.$table ).append( this.$page );


        // 表格
        this.tdWidthArr = []; // 存放每个td 的 宽度百分比

        // 分页（链接整个插件。每次 reloadData 都更新这些数据；用户对表格的所有操作 都修改这些数据，reloadData 时用这些数据更新 this.data）
        this.totalPages = 1; // 总页数
        this.total = 0; // 记录总条数
        this.currentPage = 1; // 当前页号
        this.pageSize = 50; // 每页显示 记录条数

        // ajax 获取表格数据 传入的参数
        this.data = { index: null, order: null, page: null, page_size: null };
        this.initTable( data );// 创建表格
    };

    // 创建表格（handle 是承载表格 的容器）
    jqGrid.prototype.initTable = function( dataObj ){

        if( this.colName.length != this.colModal.length ){
            alert('colName 和 colModal 的长度不一致！');
            return;
        }

        this.setTdWidth();// 求一行中 每个td 的 宽度百分比
        this.setThead();// 设置 表格thead
        this.reloadData( dataObj );// 获取表格数据（设置 tbody + 翻页按钮）
    };

    // 读取数据（只修改tbody 和 翻页按钮，可由用户调用，传入限制条件data，是否从第一页开始加载）
    jqGrid.prototype.reloadData = function( dataObj, isFirstPage ){

        // 更新 this.data
        this.data.page = this.currentPage;// 要读取的 页号
        this.data.page_size = this.pageSize;// 要读取的 记录条数

        // 根据传入的参数，合并 this.data
        if( dataObj ) this.data = $.extend( this.data, dataObj );
        if( isFirstPage ) this.data.page = 1;// 从第一页开始加载
        //console.log( this.data );

        // 加载 提示
        this.$table.find('.jqGrid-body').html('<div class="loading"><span>加载中…</span></div>');

        // 延迟，模拟从服务器读入数据的时候
        //setTimeout(function(){ /////////////////////////////////////////////////  删掉

            //this.postData( this.url, this.data, function(data){
            momo.sendPost( this.data, this.url, function(data){

                // 根据返回的数据，更新 程序数据（当前页号、总页数、每页显示条数、总条数、每页显示记录条数）
                this.currentPage = data.page.current_page;/////////////////////////////////////////////////  加回来
                //this.currentPage = this.data.page;/////////////////////////////////////////////////  删掉
                this.totalPages = data.page.total_pages;
                this.total = data.page.total;
                this.pageSize = this.data.page_size;// 每页显示 记录条数


                // 设置 thead 中 全选按钮 处于非全选状态
                this.$table.find('.selectAll').prop('checked', false);
                //console.log( data );

                // 设置 表格tbody
                this.$table.find('.jqGrid-body').html('<table><tbody></tbody></table>'); // 清除加载
                this.setTbody( data.data );

                // 提示
                if( !data.data.length ){
                    //this.$page.find('.tipBox').text('暂无数据显示');
                    this.$page.find('.tipBox').text('');
                }else{
                    this.$page.find('.tipBox').text('每页显示' + this.pageSize + '条记录，共' + this.total + '条，共' + this.totalPages + '页');
                }

                // 设置 页号按钮
                this.initPage.call( this, this.currentPage, this.totalPages );

                this.$table.trigger('jqGridReloadFinish');//发送一个事件，表示表格reload完毕

            }.bind( this ), function( err ){
                alert('获取表格数据失败！');
            });

        //}.bind(this), 2000);
    };

    jqGrid.prototype.reloadUploadFile = function( dataObj ){


        // 加载 提示
        this.$table.find('.jqGrid-body').html('<div class="loading"><span>加载中…</span></div>');

        // 延迟，模拟从服务器读入数据的时候
        //setTimeout(function(){ /////////////////////////////////////////////////  删掉

        //this.postData( this.url, this.data, function(data){
        momo.upload( dataObj, this.url, function(data){

            // 根据返回的数据，更新 程序数据（当前页号、总页数、每页显示条数、总条数、每页显示记录条数）
            this.currentPage = 1;/////////////////////////////////////////////////  加回来
            //this.currentPage = this.data.page;/////////////////////////////////////////////////  删掉
            this.totalPages = 1;
            this.total = data.page.total;
            this.pageSize = 10000;// 每页显示 记录条数


            // 设置 thead 中 全选按钮 处于非全选状态
            this.$table.find('.selectAll').prop('checked', false);
            //console.log( data );

            // 设置 表格tbody
            this.$table.find('.jqGrid-body').html('<table><tbody></tbody></table>'); // 清除加载
            this.setTbody( data.data );

            // 提示
            if( !data.data.length ){
                //this.$page.find('.tipBox').text('暂无数据显示');
                this.$page.find('.tipBox').text('');
            }else{
                this.$page.find('.tipBox').text('每页显示' + this.pageSize + '条记录，共' + this.total + '条，共' + this.totalPages + '页');
            }

            // 设置 页号按钮
            this.initPage.call( this, this.currentPage, this.totalPages );

            this.$table.trigger('jqGridReloadFinish');//发送一个事件，表示表格reload完毕

        }.bind( this ), function( err ){
            alert('获取表格数据失败！');
        });

    };


    // 移除表格（this 指向 表格）
    jqGrid.prototype.removeTable = function(){

        // 表格
        if( this.$table ){
            this.$table.remove();// 从 页面中移除
        }

        // 翻页按钮
        if( this.$page ) {
            this.$page.remove();// 从 页面中移除
        }

        this.handle.empty();// 清空所有内容
        this.$table = null;
        this.$page =  null;
    };

///////////////////////////// 一般不在外部调用的函数 /////////////////////////////////////////////

    // 【翻页按钮】

    // 只显示5个翻页按钮。除了 第一第二个、倒数第一第二个 翻页按钮，其他按钮在被选中的时候处于中间
    jqGrid.prototype.initPage = function( currentPage, totalPages ){

        var _self = this;
        currentPage = parseInt( currentPage );
        totalPages = parseInt( totalPages );
        //console.log( currentPage );
        //console.log( totalPages );

        // 无数据
        if( !totalPages ){
            $('.pageBox', _self.$page).empty();
            return;
        }

        // 清除数据，添加 “上一页”“下一页”按钮
        $('.pageBox', _self.$page).html( $('<li class="prevBtn"> << </li> <li class="nextBtn"> >> </li> ' +
            '<input type="number" placeholder="页号" min="1" max="' + totalPages + '"> <button class="jumpBtn">跳转</button> ' +
            '<select class="limitSelect"><option value="10">10</option><option value="20">20</option>' +
            '<option value="50">50</option><option value="100">100</option></select>') );

        $('.limitSelect').val( this.pageSize );// 显示数据条数
        this.addLimitSelectEvent();// 给 每页显示记录条数下拉列表 添加事件
        this.addJumpPageEvent();// 给“跳转”按钮添加点击事件

        // 添加数字按钮。 只显示5个翻页按钮
        var _content = '';
        if( totalPages <= 5 ){ // 少于等于5页
            _content = returnContentStr( 1, totalPages );
        }else{ // 多于5页
            if( currentPage <= 2 ){ // 第一第二页
                _content = returnContentStr( 1, 5 );
            }else if( currentPage >= totalPages - 1 ){ // 倒数第一第二页
                _content = returnContentStr( totalPages - 4, totalPages );
            }else {
                _content = returnContentStr( currentPage - 2, currentPage + 2 );
            }
        }
        $('.nextBtn', _self.$page).before( _content );// 在 “下一页”按钮前面添加 页号按钮

        // 返回 翻页按钮 内容部分的字符串（参数 左闭右闭）
        function returnContentStr( startIndex, endIndex ){
            var _content = '';
            for( var i = startIndex; i <= endIndex; i++ ){
                if( currentPage == i ){
                    _content += '<li class="page active">' + i + '</li>';
                }else{
                    _content += '<li class="page">' + i + '</li>';
                }
            }
            return _content;
        }

    };

    // 给 翻页按钮 添加点击事件
    jqGrid.prototype.addPageEvent = function(){

        var _self = this;

        // 数字按钮
        _self.$page.on('click', '.page', function(){
            _self.currentPage = parseInt( $(this).text() );// 设置当前页号
            _self.reloadData();// 获取数据
        });

        // 上一页
        _self.$page.on('click', '.prevBtn', function(){
            if( _self.currentPage == 1 ) return;
            _self.currentPage --; // 设置当前页号
            _self.reloadData();// 获取数据
        });

        // 下一页
        _self.$page.on('click', '.nextBtn', function(){
            if( _self.currentPage == _self.totalPages ) return;
            _self.currentPage ++; // 设置当前页号
            _self.reloadData();// 获取数据
        });

        // 鼠标停放在 按钮上方 触发

        // 上一页
        _self.$page.on('mouseover', '.prevBtn', function(){
            if( _self.currentPage == 1 ) $(this).addClass('notAllow');
            else $(this).addClass('allow');
        });

        // 下一页
        _self.$page.on('mouseover', '.nextBtn', function(){
            if( _self.currentPage == _self.totalPages ) $(this).addClass('notAllow');
            else $(this).addClass('allow');
        });

    };

    // 给 刷新按钮 添加点击事件
    jqGrid.prototype.addRefreshEvent = function(){
        var _self = this;
        _self.$page.find('.fa-refresh').click( function() {
            _self.reloadData();
        });
    };

    // 给 删除按钮 添加点击事件
    jqGrid.prototype.addTrashEvent = function(){

        var _self = this;
        _self.$page.find('.fa-trash').click( function(){

            var checkedArr = _self.$table.find('tbody').find('input[type=checkbox]:checked');// 已选择

            if( !checkedArr.length ){
                alert('请选择要删除的记录！');
                return;

            }else{
                if( confirm('确定删除选择的记录?') ){

                    var count = 0;// 已删除的记录数

                    // 不断查询，是否删除成功
                    var temp = setInterval( function(){
                        if( count < 0 ){
                            clearInterval(temp);// 取消 不断查询
                            alert('删除记录失败！');

                        }else if( count >= checkedArr.length ){ // 已经 全部删除
                            clearInterval(temp);// 取消 不断查询
                            alert('删除记录成功！');
                            _self.reloadData();
                        }
                    }, 50);

                    for( var i=0; i < checkedArr.length; i++ ) { // 逐条删除
                        (function( index ){

                            var _id = checkedArr.eq(index).attr('id').split('_')[1];
                            console.log( _id );// 输出id

                            _self.postData( _self.editUrl, { 'id': _id }, function (data) {
                                count++;
                            }, function (err) {
                                count = -1; // 删除记录失败！
                            });

                        })(i);
                    }

                }
            }

        });
    };

    // 给 输入页号 跳转按钮 添加点击事件
    jqGrid.prototype.addJumpPageEvent = function(){

        var _self = this;

        // 点击跳转按钮
        $('.pageBox .jumpBtn', _self.$page).click( function(){
            jumpPage.call( _self );
        });

        // 输入框回车
        _self.$page.find('.pageBox input[type=number]').keyup( function( event ){
            if( event.keyCode == 13 ){ // 回车键
                jumpPage.call( _self );
            }
        });

        // 事件处理函数（this 是 _self）
        function jumpPage(){

            var _val = this.$page.find('.pageBox input[type=number]').val();

            // 不法输入
            if( _val <= 0) _val = 1;
            else if( _val > this.totalPages ) _val = this.totalPages;

            this.currentPage = parseInt( _val );
            this.reloadData();// 重新加载数据
        }
    };

    // 给 选择每页显示记录条数 下拉列表 添加点击事件
    jqGrid.prototype.addLimitSelectEvent = function(){

        var _self = this;
        $('.pageBox .limitSelect', _self.$page).change( function(){

            _self.pageSize = parseInt( $(this).val() );// 每页显示记录条数
            //console.log( _self.pageSize );

            _self.reloadData( {}, true );// 从首页开始加载
        });
    };


    // 【表格】

    // 求一行中 每个td 的 宽度百分比
    jqGrid.prototype.setTdWidth = function(){

        var totalWidth = 0;// 总长度（用于求td的百分比）
        for( var i=0; i < this.colModal.length; i++ ){
            totalWidth += parseInt( this.colModal[i].width );
        }
        //console.log( totalWidth );

        if( this.isSelectAll ){ // 有全选按钮
            totalWidth += totalWidth * 0.01;// 占比： 0.01 / 1.01
        }
        
        this.tdWidthArr = [];// 清空数组
        for( var i=0; i < this.colModal.length; i++ ){ // 每个 td 宽度
            this.tdWidthArr.push( ( parseInt( this.colModal[i].width ) / totalWidth * 100 ).toFixed(2) );
        }

        if( this.isSelectAll ){ // 有全选按钮
            this.tdWidthArr[this.colModal.length] = ( ( 0.01 / 1.01 ) * totalWidth ).toFixed(2);
        }
    };

    // 设置 表格thead
    jqGrid.prototype.setThead = function(){

        var _str = '<tr>';
        if( this.isSelectAll ){ // 有全选按钮
            _str += '<th style="width: ' + this.tdWidthArr[this.colModal.length] + '%;">'
                    + '<input type="checkbox" class="selectAll"></th>';
        }

        for( var i=0; i < this.colName.length; i++ ){ // thead

            if( this.colModal[i].sort ){
                _str += '<th style="cursor: pointer; width: ' + this.tdWidthArr[i] + '%" index="' + this.colModal[i].index + '">'
                    + this.colName[i] + '<span class="sort"></span></th>';

            }else{
                _str += '<th style="width: ' + this.tdWidthArr[i] + '%">' + this.colName[i] + '</th>';
            }
        }
        _str += '</tr>';

        this.$table.find('thead').html( $(_str) );// 插入到表格

        this.addSelectAllEvent();// 给 全选按钮 添加点击事件
        this.addSortEvent();// 给 排序按钮 添加点击事件

    };

    // 设置 表格tbody
    jqGrid.prototype.setTbody = function( data ){
        var _str = '';
        if( !data.length ){ //没数据时
            _str = '<tr><td>暂无数据！</td></tr>';
        }
        for( var i=0; i < data.length; i++ ){

            _str += '<tr>';

            if( this.isSelectAll ){ // 有全选按钮
                _str += '<td style="width: ' + this.tdWidthArr[this.colModal.length] + '%;">'
                      + '<input type="checkbox" id="' + this.handle.attr('id') + '_' + data[i].id + '"></td>';
            }
            for( var j=0; j < this.colModal.length; j++ ){

                // console.log( this.colModal[j].index );// td 的 index

                var _colModal = this.colModal[j];
                var _content = data[i][_colModal.index];//  td 默认显示的内容（后台返回的内容）

                if( _colModal.formatter ){ // 程序员自定义 td 内容（调用函数 的参数：本行的所有数据、本行本列的数据、本行所在表格当前页的行数）
                    _content = _colModal.formatter( _content, data[i], i );

                    if( _colModal.textOverflowEllipsis ) {
                        _str += '<td class="textOverflowEllipsis" style="width: ' + this.tdWidthArr[j] + '%;">' + _content + '</td>';
                    }else{
                        _str += '<td style="width: ' + this.tdWidthArr[j] + '%;">' + _content + '</td>';
                    }

                }else{
                    _content = notNullOrUndefined( _content );// 不显示 null、undefined

                    // 超出部分  省略号 / 换行 显示
                    if( _colModal.textOverflowEllipsis ){
                        _str += '<td class="textOverflowEllipsis" style="width: ' + this.tdWidthArr[j] + '%;" title=' + _content + '>' + _content + '</td>';
                    }else {
                        _str += '<td style="width: ' + this.tdWidthArr[j] + '%;" title=' + _content + '>' + _content + '</td>';
                    }

                }
            }
            _str += '</tr>';
        }
        this.$table.find('tbody').html( $(_str) );// 插入到表格


        // （辅助函数）如果数据为null或undefined，替换字符串为空
        function notNullOrUndefined( str ){
            return ( str == null  ||  str == undefined  ?  '' : str );
        }
    };

    //  给 全选 添加点击事件
    jqGrid.prototype.addSelectAllEvent = function(){
        var _self = this;

        // 全选 checkbox
        $('.selectAll', _self.$table).click( function(){
            var checkboxArr = _self.$table.find('tbody').find('input[type=checkbox]');
            for( var i=0; i < checkboxArr.length; i++ ){
                checkboxArr.eq(i).prop('checked', $(this).prop('checked') );
            }
        });

        // tbody 的checkbox（点击时更新 全选checkbox 按钮状态）
        _self.$table.on( 'click', 'tbody input[type=checkbox]', function(){
            var _tbody = _self.$table.find('tbody');
            console.log( _tbody.find('[type=checkbox]:checked').length );// tbody 被选中的checkbox 数目

            $('.selectAll', _self.$table).prop( 'checked', _tbody.find('[type=checkbox]:checked').length == _tbody.find('[type=checkbox]').length );
        });

    };

    // 给 排序按钮 添加点击事件
    jqGrid.prototype.addSortEvent = function(){

        var _self = this;
        $('.sort', this.$table).parent('th').click( function(){

            // 修改 排序按钮 样式
            $(this).siblings().children('span').removeClass('sort-asc').removeClass('sort-desc').addClass('sort');

            var $span = $(this).children('span');
            if( $span.hasClass('sort-asc') ){ // 升序 -> 降序
                $span.removeClass('sort-asc').addClass('sort-desc');

            }else if( $span.hasClass('sort-desc') ){ // 降序 -> 升序
                $span.removeClass('sort-desc').addClass('sort-asc');

            }else{ // 无 -> 升序
                $span.removeClass('sort').addClass('sort-asc');
            }

            // 重新加载数据
            var _index = $(this).attr('index');
            var _order = $(this).children('span').attr('class').split('-')[1];

            _self.data.index = _index;
            _self.data.order = _order;
            _self.reloadData();// 获取表格数据
        });
    };

//////////////////////////////////////////////////////////////////////////////////////////////////////

    // 获取 后台数据
    jqGrid.prototype.postData = function( url, data, successFunc, errFunc ){
        $.ajax({
            url : url,
            data : data,
            type: 'POST',
            success: function( data ){ successFunc(data); },
            error: function( err ){ errFunc(err); }
        })
    };


    // 添加到 jQuery中
    $.jqGrid = jqGrid;

})(jQuery);
